package it.blueocean.acanto.taglibrary.jsp.taglib.tags.dataset;

import it.blueocean.acanto.taglibrary.jsp.taglib.tags.AbstractComponentStateBean;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.dataset.filter.AndListDatasetFilter;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.dataset.filter.DatasetFilter;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.dataset.filter.OrListDatasetFilter;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.dataset.filter.SimpleDatasetFilter;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.utils.HashCodeUtil;
import it.blueocean.acanto.taglibrary.jsp.taglib.tags.utils.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class DataSetStateBean extends AbstractComponentStateBean implements DataSet, Cloneable
{
	private static final long serialVersionUID = 7067819154990827160L;

	private final static Logger logger_ = LoggerFactory.getLogger(DataSetStateBean.class);

	private String query_;

	private Object providedConnection_;

	private int currentPage_;

	private int currentRow_;

	private int resultsPerPage_;

	private OrderByClause orderBy_;

	private DatasetFilter filter_;

	private List queryParameters_ = new ArrayList();

	public DataSetStateBean()
	{
		this.currentPage_ = 1;
		this.currentRow_ = 1;
		this.resultsPerPage_ = -1;
		this.query_ = "";
	}

	public int getAvailablePages()
	{
		if(getResultsPerPage() <= 0)
			return 1;
		return (int) Math.ceil(getAvailableRows() / getResultsPerPage());
	}

	public long getAvailableRows()
	{
		return getQueryExecutionResult().getAvailableRows();
	}

	public void setQuery(String paramString)
	{
		if(this.query_.equals(paramString))
			return;
		this.query_ = paramString;
		this.currentPage_ = 1;
		this.currentRow_ = 1;
	}

	public String getQuery()
	{
		return this.query_;
	}

	public int getCurrentPage()
	{
		return this.currentPage_;
	}

	public void setCurrentPage(int paramInt)
	{
		if(this.currentPage_ == paramInt)
			return;
		this.currentPage_ = paramInt;
		this.currentRow_ = ((paramInt - 1) * this.resultsPerPage_ + 1);
	}

	public void setCurrentPage(String paramString)
	{
		setCurrentPage(Integer.valueOf(paramString).intValue());
	}

	public long getCurrentRow()
	{
		return this.currentRow_;
	}

	public void setCurrentRow(int paramInt)
	{
		this.currentRow_ = paramInt;
		if(this.resultsPerPage_ <= 0)
			return;
		this.currentPage_ = ((paramInt - 1) / this.resultsPerPage_ + 1);
	}

	public void setCurrentRow(String paramString)
	{
		setCurrentRow(Integer.valueOf(paramString).intValue());
	}

	public String getFilter()
	{
		if(this.filter_ != null)
			return this.filter_.toString();
		return "";
	}

	public DatasetFilter getDatasetFilter()
	{
		return this.filter_;
	}

	public String getOrderBy()
	{
		return ((this.orderBy_ != null) ? this.orderBy_.toString() : null);
	}

	public OrderByClause getOrderByClause()
	{
		return this.orderBy_;
	}

	public void setFilterAnd(String[] paramArrayOfString)
	{
		if((paramArrayOfString == null) || (paramArrayOfString.length == 0))
		{
			this.filter_ = null;
			return;
		}
		setFilter(new AndListDatasetFilter(paramArrayOfString));
	}

	public void setFilterOr(String[] paramArrayOfString)
	{
		if((paramArrayOfString == null) || (paramArrayOfString.length == 0))
		{
			this.filter_ = null;
			return;
		}
		setFilter(new OrListDatasetFilter(paramArrayOfString));
	}

	public void setFilter(String paramString)
	{
		if(paramString == null)
			return;
		setFilter(new SimpleDatasetFilter(paramString));
	}

	public void setFilter(DatasetFilter paramDatasetFilter)
	{
		int i = 1;
		if((this.filter_ == null) && (paramDatasetFilter == null))
			i = 0;
		else if((this.filter_ == null) && (paramDatasetFilter != null))
			i = 1;
		else if((this.filter_ != null) && (paramDatasetFilter == null))
			i = 1;
		else if((this.filter_.getFilterString().equals(paramDatasetFilter.getFilterString()))
				&& (this.filter_.getFilterParams().equals(paramDatasetFilter.getFilterParams())))
			i = 0;
		if(i == 0)
			return;
		this.filter_ = paramDatasetFilter;
		this.currentPage_ = 1;
		this.currentRow_ = 1;
	}

	public void setOrderBy(String paramString)
	{
		if("".equals(paramString))
			paramString = null;
		OrderByClause localOrderByClause;
		if(paramString == null)
			localOrderByClause = null;
		else
			localOrderByClause = new OrderByClause(paramString);
		if((this.orderBy_ != null) && (this.orderBy_.equalsIgnoreDirection(localOrderByClause)))
			this.orderBy_.reverseDirection();
		else
			this.orderBy_ = localOrderByClause;
		this.currentPage_ = 1;
		this.currentRow_ = 1;
	}

	public int getResultsPerPage()
	{
		return this.resultsPerPage_;
	}

	public void setResultsPerPage(int paramInt)
	{
		this.resultsPerPage_ = paramInt;
		this.currentPage_ = ((this.currentRow_ - 1) / this.resultsPerPage_ + 1);
	}

	public void setResultsPerPage(String paramString)
	{
		if((paramString.length() == 0) || (paramString.equalsIgnoreCase("all")))
			setResultsPerPage(-1);
		setResultsPerPage(Integer.valueOf(paramString).intValue());
	}

	public Object[] getRows()
	{
		return getQueryExecutionResult().getRows();
	}

	public Object getRow()
	{
		return getRows()[(this.currentRow_ - 1)];
	}

	public Object getField(int paramInt, String paramString) throws Exception
	{
		Object localObject = getRows()[paramInt];
		return ObjectUtils.getProperty(paramString, localObject);
	}

	public long getFirstRowNumber()
	{
		return ((this.currentPage_ - 1) * this.resultsPerPage_ + 1);
	}

	public void setParam(Object paramObject)
	{
		this.queryParameters_.add(paramObject);
	}

	public void setParams(String[] paramArrayOfString)
	{
		for (int i = 0; i < paramArrayOfString.length; ++i)
			this.queryParameters_.add(paramArrayOfString[i]);
	}

	public List getParams()
	{
		return this.queryParameters_;
	}

	public QueryExecutionResult getQueryExecutionResult()
	{
		int i = getResultsPerPage() * (getCurrentPage() - 1);
		if(i < 0)
			i = 0;
		if(getResultsPerPage() <= 0)
			i = 0;
		try
		{
			try
			{
				QueryExecutionResult localQueryExecutionResult1 = executeQuery(i, getResultsPerPage());
				int k;
				if(getResultsPerPage() > 0)
					k = (int) Math.ceil(localQueryExecutionResult1.getAvailableRows() / getResultsPerPage());
				else
					k = 1;
				if(getCurrentPage() < 1)
				{
					setCurrentPage(1);
				}
				else if(getCurrentPage() > k)
				{
					setCurrentPage(k);
					localQueryExecutionResult1 = getQueryExecutionResult();
					return localQueryExecutionResult1;
				}
				if(getCurrentRow() < 1L)
					setCurrentRow(1);
				if(getCurrentRow() > localQueryExecutionResult1.getAvailableRows())
					setCurrentRow(localQueryExecutionResult1.getAvailableRows());
				QueryExecutionResult localQueryExecutionResult2 = localQueryExecutionResult1;
				return localQueryExecutionResult2;
			}
			finally
			{
			}
		}
		catch (Exception localException)
		{
			logger_.error("Exception executing query", localException);
		}
		return null;
	}

	protected abstract QueryExecutionResult executeQuery(int paramInt1, int paramInt2) throws Exception;

	public int hashCode()
	{
		int i = 23;
		i = HashCodeUtil.hash(i, getId());
		i = HashCodeUtil.hash(i, getQuery());
		i = HashCodeUtil.hash(i, getParams());
		return i;
	}

	public boolean equals(Object paramObject)
	{
		if(paramObject instanceof DataSetStateBean)
		{
			DataSetStateBean localDataSetStateBean = (DataSetStateBean) paramObject;
			boolean bool = true;
			bool &= ((getId() == null) ? false : (localDataSetStateBean.getId() == null) ? true : getId().equals(
					localDataSetStateBean.getId()));
			bool &= ((getQuery() == null) ? false : (localDataSetStateBean.getQuery() == null) ? true : getQuery()
					.equals(localDataSetStateBean.getQuery()));
			bool &= ((getParams() == null) ? false : (localDataSetStateBean.getParams() == null) ? true : getParams()
					.equals(localDataSetStateBean.getParams()));
			return bool;
		}
		return super.equals(paramObject);
	}

	public String toString()
	{
		StringBuffer localStringBuffer = new StringBuffer();
		if(getId() != null)
			localStringBuffer.append(getId());
		else
			localStringBuffer.append("<stateless>");
		localStringBuffer.append(" - ");
		localStringBuffer.append(getQuery());
		localStringBuffer.append(" - ");
		localStringBuffer.append(getParams());
		return localStringBuffer.toString();
	}

	public Object getConnection()
	{
		return this.providedConnection_;
	}

	public void setConnection(Object paramObject)
	{
		this.providedConnection_ = paramObject;
	}

	public Object clone() throws CloneNotSupportedException
	{
		return super.clone();
	}
}
